/*
 * Copyright (c) 2008 VMware, Inc.
 * Copyright (c) 2009 John Pritchard, WTKX Project Group
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package wtkx;

import wtkx.collections.ArrayList;
import wtkx.collections.Sequence;
import wtkx.util.ImmutableIterator;
import wtkx.util.ListenerList;
import wtkx.wtk.MenuBarListener;
import wtkx.wtk.content.MenuBarItemDataDecorator;

import java.util.Iterator;

/**
 * Component representing a horizontal menu bar.
 *
 * @author gbrown
 */
public class MenuBar
    extends Container 
{

    /**
     * Item listener interface.
     *
     * @author gbrown
     */
    public interface ItemListener {
        public void menuChanged(MenuBarItem item, Menu previousMenu);
    }

    /**
     * Item sequence implementation.
     *
     * @author gbrown
     */
    public final class ItemSequence
        extends Object
        implements Sequence<MenuBarItem>, Iterable<MenuBarItem> 
    {
        ItemSequence(){
            super();
        }

        public int add(MenuBarItem item) {
            int index = getLength();
            insert(item, index);

            return index;
        }

        public void insert(MenuBarItem item, int index) {
            if (item.getMenuBar() != null) {
                throw new IllegalArgumentException("item already has a menu bar.");
            }

            MenuBar.this.add(item);
            items.insert(item, index);
            item.setMenuBar(MenuBar.this);

            menuBarListeners.itemInserted(MenuBar.this, index);
        }

        public MenuBarItem update(int index, MenuBarItem item) {
            throw new UnsupportedOperationException();
        }

        public int remove(MenuBarItem item) {
            int index = items.indexOf(item);
            if (index != -1) {
                remove(index, 1);
            }

            return index;
        }

        public Sequence<MenuBarItem> remove(int index, int count) {
            Sequence<MenuBarItem> removed = items.remove(index, count);

            for (int i = 0, n = removed.getLength(); i < n; i++) {
                MenuBarItem item = removed.get(i);
                item.setMenuBar(null);
                MenuBar.this.remove(item);
            }

            menuBarListeners.itemsRemoved(MenuBar.this, index, removed);

            return removed;
        }

        public MenuBarItem get(int index) {
            return items.get(index);
        }

        public int indexOf(MenuBarItem item) {
            return items.indexOf(item);
        }

        public int getLength() {
            return items.getLength();
        }

        public Iterator<MenuBarItem> iterator() {
            return new ImmutableIterator<MenuBarItem>(items.iterator());
        }
    }

    public class MenuBarListenerList
        extends ListenerList<MenuBarListener>
        implements MenuBarListener 
    {
        MenuBarListenerList(){
            super();
        }

        public void itemInserted(MenuBar menuBar, int index) {
            for (MenuBarListener listener : this) {
                listener.itemInserted(menuBar, index);
            }
        }

        public void itemsRemoved(MenuBar menuBar, int index, Sequence<MenuBarItem> removed) {
            for (MenuBarListener listener : this) {
                listener.itemsRemoved(menuBar, index, removed);
            }
        }

        public void activeChanged(MenuBar menuBar) {
            for (MenuBarListener listener : this) {
                listener.activeChanged(menuBar);
            }
        }
    }

    private ArrayList<MenuBarItem> items = new ArrayList<MenuBarItem>();
    private ItemSequence itemSequence = new ItemSequence();

    private boolean active = false;

    private MenuBarListenerList menuBarListeners = new MenuBarListenerList();


    public MenuBar() {
        super();
        this.installSkin(MenuBar.class);
    }


    public ItemSequence getItems() {
        return itemSequence;
    }

    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        if (this.active != active) {
            this.active = active;

            if (!active) {
                getWindow().setActiveDescendant(null);
            }

            menuBarListeners.activeChanged(this);
        }
    }

    @Override
    public Sequence<Component> remove(int index, int count) {
        for (int i = index, n = index + count; i < n; i++) {
            MenuBarItem item = (MenuBarItem)get(i);

            if (item.getMenuBar() != null) {
                throw new UnsupportedOperationException();
            }
        }

        // Call the base method to remove the components
        return super.remove(index, count);
    }

    public ListenerList<MenuBarListener> getMenuBarListeners() {
        return menuBarListeners;
    }
}
